package com.eportal.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayOpenAuthTokenAppRequest;
import com.alipay.api.response.AlipayOpenAuthTokenAppResponse;
import com.eportal.aop.LogAnnotation;
import com.eportal.base.BaseDAO;
import com.eportal.dao.FeeAlipayAuthEntityMapper;
import com.eportal.domain.FeeAlipayAuth;
import com.eportal.domain.Sysopt;
import com.eportal.entity.FeeAlipayAuthEntity;
import com.eportal.service.BaseServiceImpl;
import com.eportal.service.FeeAlipayAuthService;
import com.eportal.util.Config;
import com.eportal.util.ValidateUtil;
import com.framework.jqgrid.JqGridPager;
import com.framework.jqgrid.PageEntity;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("feeAlipayAuthService")
public class FeeAlipayAuthServiceImpl extends BaseServiceImpl<FeeAlipayAuthEntity> implements FeeAlipayAuthService{

	private Map<String, Object> result = new HashMap<String, Object>();
	private Logger log = Logger.getLogger(FixServiceImpl.class);
	public HttpSession getSession() {
       return ServletActionContext.getRequest().getSession();
    }
	static String getUrl(Long sid) {
//		https://openauth.alipay.com/oauth2/appToAppAuth.htm?app_id=2015101400446982&redirect_uri=http%3A%2F%2Fexample.com
		StringBuffer url= new StringBuffer();
		url.append("https://openauth.alipay.com/oauth2/appToAppAuth.htm");
		url.append("?app_id=");
		url.append(Config.ALIPAYAPPID);
		url.append("&redirect_uri=");
		url.append(Config.ALIPAYRETURNURL);
		url.append("?sid=");
		url.append(sid);
		return url.toString();
	}
	@Resource(name="dao")
	private BaseDAO dao;

	@Resource
	private FeeAlipayAuthEntityMapper feeAlipayAuthDao;


	@Override
	public List<FeeAlipayAuth> list(String agtCode, String auth_status) {
		String hql="from FeeAlipayAuth where agtcode='"+agtCode+"' and auth_status='"+auth_status+"'";
		 return dao.query(hql);
	}

	@Override
	public List<Map<String, Object>> list(JqGridPager jqGridPager) {
		String SQL = "select t.*,to_char(t.ctime,'yyyy-mm-dd HH24:mi:ss') as ctime1 from FEE_ALIPAY_AUTH t left join t02_agtent a on t.agtcode=a.agtcode ";
		log.info(SQL);
	     return dao.query(SQL, jqGridPager);
	}

	@Override
	public FeeAlipayAuth getFeeAlipayAuth(Long sid) {
		FeeAlipayAuth feeAlipayAuth = (FeeAlipayAuth) dao.getById(FeeAlipayAuth.class, sid);
		return feeAlipayAuth;
	}

	private FeeAlipayAuth getFeeAlipayAuth(String where) {
		StringBuffer sb = new StringBuffer("from FeeAlipayAuth t where ");
		sb.append(where);
		return (FeeAlipayAuth) dao.loadObject(sb.toString());
	}

	@Override
	@LogAnnotation(operateDescribe="支付宝授权保存")
	public Map<String, Object> addMethod(FeeAlipayAuth feeAlipayAuth) {
		try {
			String msg = ValidateUtil.validate(feeAlipayAuth);
		    if (msg == null || msg.trim().length() == 0) {
				result = new HashMap<String, Object>();
	        	Sysopt  user= (Sysopt)getSession().getAttribute("user");
	        	Map<String, Object> map = haveExist(feeAlipayAuth);
	        	if(!(boolean) map.get("code")){
	        		result.put("code", 0);
		            result.put("msg", map.get("msg"));
		            return result;
	        	}
	        	feeAlipayAuth.setAgtcode(user.getAgtCode());
	        	feeAlipayAuth.setCtime(new Date());
	        	feeAlipayAuth.setCusername(user.getUserName());
	        	feeAlipayAuth.setAuthStatus("1");
	        	save(feeAlipayAuth);
	        	result.put("objectId", feeAlipayAuth.getSid());
	            result.put("code", 1);
	            result.put("msg", "添加成功");
	            //支付宝返回url
	            String url = getUrl(feeAlipayAuth.getSid());
	            result.put("url", url);
		    } else {
	        	result.put("code", 0);
	            result.put("msg", msg);
	        }
		} catch (Exception e) {
			log.error("添加支付宝失败", e);
			result.put("code", 0);
			result.put("msg", "添加支付宝失败,请重试");
		}
		return result;
	}

	/**
	 *
	 * @param feeAlipayAuth
	 * @see  FeeAlipayAuthServiceImpl#haveExist(FeeAlipayAuthEntity)  mybatis版
	 * @return
	 */
	private Map<String, Object> haveExist(FeeAlipayAuth feeAlipayAuth) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", true);
		String where =" t.pid='"+feeAlipayAuth.getPid()+"' and t.sid<>"+feeAlipayAuth.getSid();
		FeeAlipayAuth entry = getFeeAlipayAuth(where);
		if (entry != null) {
			map.put("code", false);
			map.put("msg", "所填写的支付宝pid重复，请确认后填写");
			return map;
		}
		String where2 =" t.alipayAppid='"+feeAlipayAuth.getAlipayAppid()+"'  and t.sid<>"+feeAlipayAuth.getSid();
		FeeAlipayAuth entry2 = getFeeAlipayAuth(where2);
		if (entry2 != null) {
			map.put("code", false);
			map.put("msg", "所填写的支付宝应用id重复，请确认后填写");
			return map;
		}
		String where3 =" t.loginAccount='"+feeAlipayAuth.getLoginAccount()+"'  and t.sid<>"+feeAlipayAuth.getSid();
		FeeAlipayAuth entry3 = getFeeAlipayAuth(where3);
		if (entry3 != null) {
			map.put("code", false);
			map.put("msg", "所填写的支付宝登录账号重复，请确认后填写");
		}
		return map;
	}
	private FeeAlipayAuth save(FeeAlipayAuth feeAlipayAuth) throws Exception {
		dao.save(feeAlipayAuth);
    	return feeAlipayAuth;
	}

	@Override
	@LogAnnotation(operateDescribe="支付宝再次授权")
	public Map<String, Object> updateMethod(FeeAlipayAuth feeAlipayAuth) {
		String msg = ValidateUtil.validate(feeAlipayAuth);
		result = new HashMap<String, Object>();
		result.put("objectId", feeAlipayAuth.getSid());
		if (msg == null || msg.trim().length() == 0) {
			try {
				Map<String, Object> map = haveExist(feeAlipayAuth);
	        	if(!(boolean) map.get("code")){
	        		result.put("code", 0);
		            result.put("msg", map.get("msg"));
		            return result;
	        	}
				FeeAlipayAuth entity = getFeeAlipayAuth(feeAlipayAuth.getSid());
				entity.setLoginAccount(feeAlipayAuth.getLoginAccount());
				entity.setPid(feeAlipayAuth.getPid());
				entity.setCompanyName(feeAlipayAuth.getCompanyName());
				entity.setIntro(feeAlipayAuth.getIntro());
				entity.setAlipayAppid(feeAlipayAuth.getAlipayAppid());
				entity.setPrivateKey(feeAlipayAuth.getPrivateKey());
				entity.setPublicKey(feeAlipayAuth.getPublicKey());
				entity.setAlipayPrivateKey(feeAlipayAuth.getAlipayPrivateKey());
				entity.setAlipayPublicKey(feeAlipayAuth.getAlipayPublicKey());
	        	dao.update(entity);
	            //支付宝返回url
	            String url = getUrl(feeAlipayAuth.getSid());
	            result.put("url", url);
	            result.put("code", 1);
	        } catch (Exception e) {
	            log.error("支付宝再次授权修改失败", e);
	            result.put("code", 0);
	            result.put("msg", "支付宝再次授权修改失败");
	        }
	    } else {
        	result.put("code", 0);
            result.put("msg", msg);
        }
		 return result;
	}
	@Override
	@LogAnnotation(operateDescribe="支付宝授权删除")
	public Map<String, Object> deleteMethod(String ids) {
		try {
			result = new HashMap<String, Object>();
        	result.put("objectId", ids);
            String[] sparams = ids.split(",");
            FeeAlipayAuth feeAlipayAuth;
            for (String s : sparams) {
            	feeAlipayAuth = getFeeAlipayAuth(Long.parseLong(s));
//            	feeAlipayAuth.setAdminDel("2");
            	dao.update(feeAlipayAuth);
            }
            result.put("code", 1);
            result.put("msg", "删除支付宝授权成功");
        } catch (Exception e) {
            log.error("删除支付宝授权失败", e);
            result.put("code", 0);
            result.put("msg", "删除支付宝授权失败");
        }
        return result;
	}


	@Override
	public Map<String, String> getDetailBySql(String sql) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Object> codeChangeTokenMethod(String sid, String app_id, String app_auth_code) {
		try {
		result = new HashMap<String, Object>();

		//根据code,置换token
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",Config.ALIPAYAPPID,Config.ALIPAY_APP_PRIVATE_KEY,"json","GBK",Config.ALIPAY_PUBLIC_KEY);
		AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
		request.setBizContent("{" +
		"    \"grant_type\":\"authorization_code\"," +
		"    \"code\":\""+app_auth_code+"\"," +
		"  }");
			AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
			if("Success".equals(response.getMsg())){
				FeeAlipayAuth entity =getFeeAlipayAuth(Long.parseLong(sid));
				String returnPid = response.getUserId();
				String returnAppPid = response.getAuthAppId();
				log.info(response.getBody());
				if(!entity.getPid().equals(returnPid)){
					 result.put("code", 0);
			         result.put("msg", "所填写的支付宝pid与获取授权所得信息不匹配，请确认后再授权");
			         return result;
				}
				if(!entity.getAlipayAppid().equals(returnAppPid)){
					 result.put("code", 0);
			         result.put("msg", "所填写的支付宝应用id与获取授权所得信息不匹配，请确认后再授权");
			         return result;
				}

				entity.setAppAuthCode(app_auth_code);//授权码
				entity.setAppAuthToken(response.getAppAuthToken());//商户授权令牌
				entity.setAppRefreshToken(response.getAppRefreshToken());//刷新令牌时使用
				int expires_in = Integer.parseInt(response.getExpiresIn());//令牌有效期
				int re_expires_in = Integer.parseInt(response.getReExpiresIn());//刷新令牌有效期

				String timestamp = String.valueOf(new Date().getTime()/1000);
				long expiresIn = Long.valueOf(timestamp)+expires_in;
				long reExpiresIn = Long.valueOf(timestamp)+re_expires_in;
				entity.setExpiresTime(new Date(expiresIn*1000));//令牌有效期
				entity.setReExpiresTime(new Date(reExpiresIn*1000));//刷新令牌有效期
				entity.setAuthStatus("2");
				dao.update(entity);
				 result.put("code", 1);
		         result.put("msg", "获取支付宝授权信息成功,请返回刷新页面查看");
			}else{
				 result.put("code", 0);
		         result.put("msg", "获取支付宝授权信息失败，请返回重新授权");
			}

		} catch (AlipayApiException e) {
			log.error(this, e);
			 result.put("code", 0);
	         result.put("msg", "获取支付宝授权信息失败，请返回重新授权");
		}
		return result;
	}



//todo ---------------------------------------------------------------------------------------------


	/**
	 * 支付宝授权管理列表
	 *
	 *
	 * @param agtCode	 合作方code
	 * @param pageEntity 分页对象
	 * @param user       当前用户
	 * @param userRole   当前用户userRole
	 * @return
	 * @author Saber
	 * @Date 2017/8/22 下午6:47
	 * @see FeeAlipayAuthServiceImpl#list(JqGridPager)
	 */
	@Override
	public PageInfo<FeeAlipayAuthEntity> queryForPage(String agtCode, PageEntity pageEntity, Sysopt user, int userRole) {
		//执行分页
		PageHelper.startPage(pageEntity.getPageNo(), pageEntity.getPageSize());
		//排序
		String orderField = pageEntity.getSort();
		String orderDirection = pageEntity.getOrder();
		if (org.apache.commons.lang3.StringUtils.isNotEmpty(orderField)) {
			PageHelper.orderBy(orderField);
			if (org.apache.commons.lang3.StringUtils.isNotEmpty(orderDirection)) {
				PageHelper.orderBy(orderField + " " + orderDirection);
			}
		}
		List<FeeAlipayAuthEntity> list = feeAlipayAuthDao.queryForList(agtCode,user,userRole);
		return new PageInfo<>(list);
	}

	/**
	 * 新增
	 *
	 * @param entity   对象
	 * @param user     当前用户
	 * @param userRole 当前用户userRole
	 * @return
	 * @author Saber
	 * @Date 2017/8/23 上午10:03
	 * @see FeeAlipayAuthServiceImpl#addMethod(FeeAlipayAuth)
	 */
	@Override
	@Transactional
	public JSONObject add(FeeAlipayAuthEntity entity, Sysopt user, int userRole) {

		JSONObject json = new JSONObject();
		try {
			//校验参数
			String msg = ValidateUtil.validate(entity);
			if (StringUtils.isBlank(msg)) {
				JSONObject checkJson = haveExist(entity);
				if(0 == checkJson.get("code")){
					json.put("code", 0);
					json.put("msg", checkJson.get("msg"));
					return json;
				}
				entity.setAgtcode(user.getAgtCode());
				entity.setCtime(new Date());
				entity.setCusername(user.getUserName());
				entity.setAuthStatus("1");
				feeAlipayAuthDao.insertSelective(entity);
				json.put("objectId", entity.getSid());
				json.put("code", 1);
				json.put("msg", "添加成功");
				json.put("data",entity.getSid());
				//支付宝返回url
				String url = getUrl(entity.getSid());
				json.put("url", url);
				return json;
			} else {
				json.put("code", 0);
				json.put("msg", msg);
				return json;
			}
		} catch (Exception e) {
			log.error("添加支付宝失败", e);
			json.put("code", 0);
			json.put("msg", "添加支付宝失败,请重试");
			return json;
		}
	}

	/**
	 * 验证支付宝信息是否重复
	 * @author Saber
	 * @Date 2017/8/23 上午10:08
	 * @param entity
	 * @see FeeAlipayAuthServiceImpl#haveExist(FeeAlipayAuth)
	 * @return
	 */
	private JSONObject haveExist(FeeAlipayAuthEntity entity) {
		JSONObject json = new JSONObject();
		FeeAlipayAuthEntity entry1 = feeAlipayAuthDao.getByPidAndSid(entity.getPid(),entity.getSid());
		if (entry1 != null) {
			json.put("code", 0);
			json.put("msg", "所填写的支付宝pid重复，请确认后填写");
			return json;
		}
		FeeAlipayAuthEntity entry2 =feeAlipayAuthDao.getbyAlipayAppidAndSid(entity.getAlipayAppid(),entity.getSid());
		if (entry2 != null) {
			json.put("code", 0);
			json.put("msg", "所填写的支付宝应用id重复，请确认后填写");
			return json;
		}
		FeeAlipayAuthEntity entry3 = feeAlipayAuthDao.getbyLoginAccountAndSid(entity.getLoginAccount(), entity.getSid());
		if (entry3 != null) {
			json.put("code", 0);
			json.put("msg", "所填写的支付宝登录账号重复，请确认后填写");
			return json;
		}
		json.put("code", 1);
		json.put("msg","ok");
		return json;
	}

	/**
	 * 支付宝授权修改
	 *
	 * @param entity   对象
	 * @param user     当前用户
	 * @param userRole 当前用户userRole
	 * @return
	 * @author Saber
	 * @Date 2017/8/23 下午1:18
	 * @see FeeAlipayAuthServiceImpl#updateMethod(FeeAlipayAuth)
	 */
	@Override
	public JSONObject update(FeeAlipayAuthEntity entity, Sysopt user, int userRole) {
		JSONObject json = new JSONObject();
		try {
			//校验参数
			String msg = ValidateUtil.validate(entity);
			if (StringUtils.isNotBlank(msg)) {
				json.put("code", 0);
				json.put("msg", msg);
				return json;
			}
			//主键必传
			if(entity.getSid() == null){
				json.put("code",0);
				json.put("msg","参数必传");
				return json;
			}

			JSONObject checkJson = haveExist(entity);
			if(0 == checkJson.get("code")){
				json.put("code", 0);
				json.put("msg", checkJson.get("msg"));
				return json;
			}
			entity.setAgtcode(user.getAgtCode());
			entity.setCtime(new Date());
			entity.setCusername(user.getUserName());
			entity.setAuthStatus("1");
			feeAlipayAuthDao.updateByPrimaryKeySelective(entity);
			json.put("objectId", entity.getSid());
			json.put("code", 1);
			json.put("msg", "修改成功");
			json.put("data",entity.getSid());
			//支付宝返回url
			String url = getUrl(entity.getSid());
			json.put("url", url);
			return json;
		} catch (Exception e) {
			log.error("支付宝再次授权修改失败", e);
			json.put("code", 0);
			json.put("msg", "支付宝再次授权修改失败");
			return json;
		}
	}

	/**
	 * 使用app_auth_code换取app_auth_token
	 *
	 * @param sid
	 * @param app_id
	 * @param app_auth_code 授权码
	 * @return
	 * @author Saber
	 * @Date 2017/8/23 下午2:19
	 * @see FeeAlipayAuthServiceImpl#codeChangeTokenMethod(String, String, String)
	 */
	@Override
	public JSONObject codeChangeToken(Long sid, String app_id, String app_auth_code) {

		JSONObject json = new JSONObject();

		try {
			//根据code,置换token
			AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",Config.ALIPAYAPPID,Config.ALIPAY_APP_PRIVATE_KEY,"json","GBK",Config.ALIPAY_PUBLIC_KEY);
			AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
			request.setBizContent("{" +
					"    \"grant_type\":\"authorization_code\"," +
					"    \"code\":\""+app_auth_code+"\"," +
					"  }");
			AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
			if("Success".equals(response.getMsg())){
				FeeAlipayAuthEntity entity =feeAlipayAuthDao.selectByPrimaryKey(sid);
				String returnPid = response.getUserId();
				String returnAppPid = response.getAuthAppId();
				log.info(response.getBody());
				if(!entity.getPid().equals(returnPid)){
					json.put("code", 0);
					json.put("msg", "所填写的支付宝pid与获取授权所得信息不匹配，请确认后再授权");
					return json;
				}
				if(!entity.getAlipayAppid().equals(returnAppPid)){
					json.put("code", 0);
					json.put("msg", "所填写的支付宝应用id与获取授权所得信息不匹配，请确认后再授权");
					return json;
				}

				entity.setAppAuthCode(app_auth_code);//授权码
				entity.setAppAuthToken(response.getAppAuthToken());//商户授权令牌
				entity.setAppRefreshToken(response.getAppRefreshToken());//刷新令牌时使用
				int expires_in = Integer.parseInt(response.getExpiresIn());//令牌有效期
				int re_expires_in = Integer.parseInt(response.getReExpiresIn());//刷新令牌有效期

				String timestamp = String.valueOf(new Date().getTime()/1000);
				long expiresIn = Long.valueOf(timestamp)+expires_in;
				long reExpiresIn = Long.valueOf(timestamp)+re_expires_in;
				entity.setExpiresTime(new Date(expiresIn*1000));//令牌有效期
				entity.setReExpiresTime(new Date(reExpiresIn*1000));//刷新令牌有效期
				entity.setAuthStatus("2");
				feeAlipayAuthDao.updateByPrimaryKeySelective(entity);
				json.put("code", 1);
				json.put("msg", "获取支付宝授权信息成功,请返回刷新页面查看");
				return json;
			}else{
				json.put("code", 0);
				json.put("msg", "获取支付宝授权信息失败，请返回重新授权");
				return json;
			}

		} catch (AlipayApiException e) {
			log.error(this, e);
			json.put("code", 0);
			json.put("msg", "获取支付宝授权信息失败，请返回重新授权");
			return json;
		}
	}
}
